package role

import (
	"fmt"
	partner "gitee.com/binny_w/gin-partner"
	"gitee.com/binny_w/gin_starter/core"
	util2 "gitee.com/binny_w/go-util/v2"
	"github.com/gin-gonic/gin"
	"net/http"
)

var MdlRole *partner.CommonModel

type ListItem struct {
	Name  string   `json:"name"`
	Bases []string `json:"bases"`
}

type ApiItem struct {
	Path string `json:"path"`
	Info string `json:"info"`
	Flag uint8  `json:"flag"`
}

func init() {
	core.WaitCore.Wait()

	MdlRole = partner.NewCommonModel()
	defer core.Engine.RouterWithModel(core.ApiGroup, MdlRole)

	// 获取列表
	_ = MdlRole.RegisterGinHandler(http.MethodGet, "/role", func(c *gin.Context) {
		rs, _ := core.Rbac.GetAllRoles()
		ret := make([]ListItem, 0, len(rs))
		for _, v := range rs {
			var bases []string
			if v != core.Rbac.SuperAdmin {
				bases, _ = core.Rbac.GetImplicitRolesForUser(v)
			}
			if bases == nil {
				bases = make([]string, 0)
			}
			ret = append(ret, ListItem{
				Name:  v,
				Bases: bases,
			})
		}
		partner.WriteJsonSuccess(c, ret)
	})

	// 页面权限查询
	_ = MdlRole.RegisterGinHandler(http.MethodGet, "/role/page/:role/:name", func(c *gin.Context) {
		role := c.Param("role")
		name := c.Param("name")
		partner.WriteJsonSuccess(c, check(role, name, false))
	})

	// 页面权限 - 修改
	_ = MdlRole.RegisterGinHandler(http.MethodPatch, "/role/page/:role", func(c *gin.Context) {
		role := c.Param("role")
		all, _ := core.Rbac.GetAllRoles()
		if role == "" || !util2.InArray(role, all) {
			partner.WriteJsonError(c, 621, "角色不存在")
			return
		}
		page := c.PostForm("page")
		flag := c.PostForm("flag")
		if page == "" || !util2.InArray(flag, []string{"1", "0"}) {
			partner.WriteJsonError(c, 622, "提交的参数错误")
			return
		}
		if flag == "1" {
			if ok, err := core.Rbac.AddPermissionForRole(role, "page", page); err != nil {
				partner.WriteJsonError(c, 623, err.Error())
				return
			} else if !ok {
				partner.WriteJsonError(c, 624, "操作失败")
				return
			}
		} else {
			if ok, err := core.Rbac.DeletePermissionForRole(role, "page", page); err != nil {
				partner.WriteJsonError(c, 623, err.Error())
				return
			} else if !ok {
				partner.WriteJsonError(c, 624, "操作失败")
				return
			}
		}
		partner.WriteJsonSuccess(c, nil)
	})

	// 接口权限列表
	_ = MdlRole.RegisterGinHandler(http.MethodGet, "/role/api/:role", func(c *gin.Context) {
		role := c.Param("role")
		all, _ := core.Rbac.GetAllRoles()
		if role == "" || !util2.InArray(role, all) {
			partner.WriteJsonError(c, 621, "角色不存在")
			return
		}
		ret := make([]ApiItem, 0)
		for _, rt := range core.Engine.E.Routes() {
			if core.IsPublicApi(rt.Method, rt.Path) || core.IsRoleLimitlessApi(rt.Method, rt.Path) {
				continue
			}
			path := fmt.Sprintf("%s:%s", rt.Method, rt.Path)
			ret = append(ret, ApiItem{
				Path: path,
				Info: "",
				Flag: 0,
			})
		}
		partner.WriteJsonSuccess(c, ret)
	})

	// 接口权限 - 查询
	_ = MdlRole.RegisterGinHandler(http.MethodGet, "/role/api/:role/info", func(c *gin.Context) {
		role := c.Param("role")
		all, _ := core.Rbac.GetAllRoles()
		if role == "" || !util2.InArray(role, all) {
			partner.WriteJsonError(c, 621, "角色不存在")
			return
		}
		path := c.Query("path")
		if path == "" {
			partner.WriteJsonError(c, 623, "API 路由为空")
			return
		}
		info, _ := core.RedisCache.GetStr("api_info:" + path)
		partner.WriteJsonSuccess(c, ApiItem{
			Path: path,
			Info: info,
			Flag: checkApi(role, path),
		})
	})

	// 接口权限列表 - 修改
	_ = MdlRole.RegisterGinHandler(http.MethodPatch, "/role/api/:role", func(c *gin.Context) {
		role := c.Param("role")
		all, _ := core.Rbac.GetAllRoles()
		if role == "" || !util2.InArray(role, all) {
			partner.WriteJsonError(c, 621, "角色不存在")
			return
		}
		path := c.PostForm("path")
		if path == "" {
			partner.WriteJsonError(c, 650, "Path 不能为空")
			return
		}
		if info, ok := c.GetPostForm("info"); ok {
			bln, err := core.RedisCache.Set("api_info:"+path, info, 0, "")
			if err != nil {
				partner.WriteJsonError(c, 656, err.Error())
				return
			}
			if !bln {
				partner.WriteJsonError(c, 657, "数据保存失败")
				return
			}
		}
		if flag, ok := c.GetPostForm("flag"); ok {
			if !util2.InArray(flag, []string{"1", "0"}) {
				partner.WriteJsonError(c, 622, "提交的参数错误")
				return
			}
			if flag == "1" {
				if ok, err := core.Rbac.AddPermissionForRole(role, "api", path); err != nil {
					partner.WriteJsonError(c, 623, err.Error())
					return
				} else if !ok {
					partner.WriteJsonError(c, 624, "操作失败")
					return
				}
			} else {
				if ok, err := core.Rbac.DeletePermissionForRole(role, "api", path); err != nil {
					partner.WriteJsonError(c, 623, err.Error())
					return
				} else if !ok {
					partner.WriteJsonError(c, 624, "操作失败")
					return
				}
			}
		}
		partner.WriteJsonSuccess(c, nil)
	})

	// 删除
	_ = MdlRole.RegisterGinHandler(http.MethodDelete, "/role/:role", func(c *gin.Context) {
		defer core.Cache.Del("all-role")
		_ = core.Rbac.DeleteRoles(c.Param("role"))
		partner.WriteJsonSuccess(c, nil)
	})

	// 添加
	_ = MdlRole.RegisterGinHandler(http.MethodPost, "/role", func(c *gin.Context) {
		role := c.PostForm("role")
		if role == "" {
			partner.WriteJsonError(c, 620, "角色名不能为空")
			return
		}
		all, _ := core.Rbac.GetAllRoles()
		if util2.InArray(role, all) {
			partner.WriteJsonError(c, 621, "角色已存在")
			return
		}
		bases := c.PostFormArray("bases[]")
		if ok, _ := core.Rbac.AddRoles(role); ok && len(bases) > 0 {
			bases1 := make([]string, 0, len(bases))
			for _, base := range bases {
				if base == core.Rbac.SuperAdmin || base == core.Rbac.UserNone || base == role {
					continue
				}
				if !util2.InArray(base, all) {
					continue
				}
				bases1 = append(bases1, base)
			}
			if len(bases1) > 0 {
				_, _ = core.Rbac.AddRolesForUser(role, bases1...)
			}
		}
		defer core.Cache.Del("all-role")
		partner.WriteJsonSuccess(c, nil)
	})

}
